/*
  author Sylvain Bertrand <sylvain.bertrand@gmail.com>
  Protected by linux GNU GPLv2
  Copyright 2012-2014
*/
#include <linux/pci.h>
#include <linux/cdev.h>

#include <alga/rng_mng.h>
#include <uapi/alga/pixel_fmts.h>
#include <alga/timing.h>
#include <alga/amd/atombios/atb.h>
#include <uapi/alga/amd/dce6/dce6.h>
#include <alga/amd/atombios/vm.h>
#include <alga/amd/atombios/cm.h>
#include <alga/amd/atombios/pp.h>
#include <alga/amd/atombios/vram_info.h>

#include "../mc.h"
#include "../rlc.h"
#include "../ih.h"
#include "../fence.h"
#include "../ring.h"
#include "../dmas.h"
#include "../ba.h"
#include "../cps.h"
#include "../gpu.h"
#include "../drv.h"

#include "../smc_regs.h"
#include "../smc.h"

#include "ctx.h"
#include "private.h"

struct reg {
	u32 of;
	u32 mask;
	u32 shift;
	u32 val;
};

static struct reg lcac_tahiti[] = {
	{ 0x143, 0x0001fffe, 1, 0x3 },
	{ 0x143, 0x00000001, 0, 0x1 },
	{ 0x146, 0x0001fffe, 1, 0x3 },
	{ 0x146, 0x00000001, 0, 0x1 },
	{ 0x149, 0x0001fffe, 1, 0x3 },
	{ 0x149, 0x00000001, 0, 0x1 },
	{ 0x14c, 0x0001fffe, 1, 0x3 },
	{ 0x14c, 0x00000001, 0, 0x1 },
	{ 0x98, 0x0001fffe, 1, 0x2 },
	{ 0x98, 0x00000001, 0, 0x1 },
	{ 0x9b, 0x0001fffe, 1, 0x2 },
	{ 0x9b, 0x00000001, 0, 0x1 },
	{ 0x9e, 0x0001fffe, 1, 0x2 },
	{ 0x9e, 0x00000001, 0, 0x1 },
	{ 0x101, 0x0001fffe, 1, 0x2 },
	{ 0x101, 0x00000001, 0, 0x1 },
	{ 0x104, 0x0001fffe, 1, 0x2 },
	{ 0x104, 0x00000001, 0, 0x1 },
	{ 0x107, 0x0001fffe, 1, 0x2 },
	{ 0x107, 0x00000001, 0, 0x1 },
	{ 0x10a, 0x0001fffe, 1, 0x2 },
	{ 0x10a, 0x00000001, 0, 0x1 },
	{ 0x10d, 0x0001fffe, 1, 0x2 },
	{ 0x10d, 0x00000001, 0, 0x1 },
	{ 0x8c, 0x0001fffe, 1, 0x8 },
	{ 0x8c, 0x00000001, 0, 0x1 },
	{ 0x8f, 0x0001fffe, 1, 0x8 },
	{ 0x8f, 0x00000001, 0, 0x1 },
	{ 0x92, 0x0001fffe, 1, 0x8 },
	{ 0x92, 0x00000001, 0, 0x1 },
	{ 0x95, 0x0001fffe, 1, 0x8 },
	{ 0x95, 0x00000001, 0, 0x1 },
	{ 0x14f, 0x0001fffe, 1, 0x8 },
	{ 0x14f, 0x00000001, 0, 0x1 },
	{ 0x152, 0x0001fffe, 1, 0x8 },
	{ 0x152, 0x00000001, 0, 0x1 },
	{ 0x155, 0x0001fffe, 1, 0x8 },
	{ 0x155, 0x00000001, 0, 0x1 },
	{ 0x158, 0x0001fffe, 1, 0x8 },
	{ 0x158, 0x00000001, 0, 0x1 },
	{ 0x110, 0x0001fffe, 1, 0x8 },
	{ 0x110, 0x00000001, 0, 0x1 },
	{ 0x113, 0x0001fffe, 1, 0x8 },
	{ 0x113, 0x00000001, 0, 0x1 },
	{ 0x116, 0x0001fffe, 1, 0x8 },
	{ 0x116, 0x00000001, 0, 0x1 },
	{ 0x119, 0x0001fffe, 1, 0x8 },
	{ 0x119, 0x00000001, 0, 0x1 },
	{ 0x11c, 0x0001fffe, 1, 0x2 },
	{ 0x11c, 0x00000001, 0, 0x1 },
	{ 0x11f, 0x0001fffe, 1, 0x2 },
	{ 0x11f, 0x00000001, 0, 0x1 },
	{ 0x122, 0x0001fffe, 1, 0x2 },
	{ 0x122, 0x00000001, 0, 0x1 },
	{ 0x125, 0x0001fffe, 1, 0x2 },
	{ 0x125, 0x00000001, 0, 0x1 },
	{ 0x128, 0x0001fffe, 1, 0x2 },
	{ 0x128, 0x00000001, 0, 0x1 },
	{ 0x12b, 0x0001fffe, 1, 0x2 },
	{ 0x12b, 0x00000001, 0, 0x1 },
	{ 0x15b, 0x0001fffe, 1, 0x4 },
	{ 0x15b, 0x00000001, 0, 0x1 },
	{ 0x15e, 0x0001fffe, 1, 0x4 },
	{ 0x15e, 0x00000001, 0, 0x1 },
	{ 0x161, 0x0001fffe, 1, 0x4 },
	{ 0x161, 0x00000001, 0, 0x1 },
	{ 0x164, 0x0001fffe, 1, 0x4 },
	{ 0x164, 0x00000001, 0, 0x1 },
	{ 0x167, 0x0001fffe, 1, 0x4 },
	{ 0x167, 0x00000001, 0, 0x1 },
	{ 0x16a, 0x0001fffe, 1, 0x4 },
	{ 0x16a, 0x00000001, 0, 0x1 },
	{ 0x16d, 0x0001fffe, 1, 0x6 },
	{ 0x16d, 0x00000001, 0, 0x1 },
	{ 0x170, 0x0001fffe, 1, 0x2 },
	{ 0x170, 0x00000001, 0, 0x1 },
	{ 0x173, 0x0001fffe, 1, 0x2 },
	{ 0x173, 0x00000001, 0, 0x1 },
	{ 0x176, 0x0001fffe, 1, 0x2 },
	{ 0x176, 0x00000001, 0, 0x1 },
	{ 0x179, 0x0001fffe, 1, 0x2 },
	{ 0x179, 0x00000001, 0, 0x1 },
	{ 0x17c, 0x0001fffe, 1, 0x2 },
	{ 0x17c, 0x00000001, 0, 0x1 },
	{ 0x17f, 0x0001fffe, 1, 0x2 },
	{ 0x17f, 0x00000001, 0, 0x1 },
	{ 0xffffffff }

};

static struct reg lcac_pitcairn[] = {
	{ 0x98, 0x0001fffe, 1, 0x2 },
	{ 0x98, 0x00000001, 0, 0x1 },
	{ 0x104, 0x0001fffe, 1, 0x2 },
	{ 0x104, 0x00000001, 0, 0x1 },
	{ 0x110, 0x0001fffe, 1, 0x5 },
	{ 0x110, 0x00000001, 0, 0x1 },
	{ 0x14f, 0x0001fffe, 1, 0x5 },
	{ 0x14f, 0x00000001, 0, 0x1 },
	{ 0x8c, 0x0001fffe, 1, 0x5 },
	{ 0x8c, 0x00000001, 0, 0x1 },
	{ 0x143, 0x0001fffe, 1, 0x2 },
	{ 0x143, 0x00000001, 0, 0x1 },
	{ 0x9b, 0x0001fffe, 1, 0x2 },
	{ 0x9b, 0x00000001, 0, 0x1 },
	{ 0x107, 0x0001fffe, 1, 0x2 },
	{ 0x107, 0x00000001, 0, 0x1 },
	{ 0x113, 0x0001fffe, 1, 0x5 },
	{ 0x113, 0x00000001, 0, 0x1 },
	{ 0x152, 0x0001fffe, 1, 0x5 },
	{ 0x152, 0x00000001, 0, 0x1 },
	{ 0x8f, 0x0001fffe, 1, 0x5 },
	{ 0x8f, 0x00000001, 0, 0x1 },
	{ 0x146, 0x0001fffe, 1, 0x2 },
	{ 0x146, 0x00000001, 0, 0x1 },
	{ 0x9e, 0x0001fffe, 1, 0x2 },
	{ 0x9e, 0x00000001, 0, 0x1 },
	{ 0x10a, 0x0001fffe, 1, 0x2 },
	{ 0x10a, 0x00000001, 0, 0x1 },
	{ 0x116, 0x0001fffe, 1, 0x5 },
	{ 0x116, 0x00000001, 0, 0x1 },
	{ 0x155, 0x0001fffe, 1, 0x5 },
	{ 0x155, 0x00000001, 0, 0x1 },
	{ 0x92, 0x0001fffe, 1, 0x5 },
	{ 0x92, 0x00000001, 0, 0x1 },
	{ 0x149, 0x0001fffe, 1, 0x2 },
	{ 0x149, 0x00000001, 0, 0x1 },
	{ 0x101, 0x0001fffe, 1, 0x2 },
	{ 0x101, 0x00000001, 0, 0x1 },
	{ 0x10d, 0x0001fffe, 1, 0x2 },
	{ 0x10d, 0x00000001, 0, 0x1 },
	{ 0x119, 0x0001fffe, 1, 0x5 },
	{ 0x119, 0x00000001, 0, 0x1 },
	{ 0x158, 0x0001fffe, 1, 0x5 },
	{ 0x158, 0x00000001, 0, 0x1 },
	{ 0x95, 0x0001fffe, 1, 0x5 },
	{ 0x95, 0x00000001, 0, 0x1 },
	{ 0x14c, 0x0001fffe, 1, 0x2 },
	{ 0x14c, 0x00000001, 0, 0x1 },
	{ 0x11c, 0x0001fffe, 1, 0x2 },
	{ 0x11c, 0x00000001, 0, 0x1 },
	{ 0x11f, 0x0001fffe, 1, 0x2 },
	{ 0x11f, 0x00000001, 0, 0x1 },
	{ 0x122, 0x0001fffe, 1, 0x2 },
	{ 0x122, 0x00000001, 0, 0x1 },
	{ 0x125, 0x0001fffe, 1, 0x2 },
	{ 0x125, 0x00000001, 0, 0x1 },
	{ 0x128, 0x0001fffe, 1, 0x2 },
	{ 0x128, 0x00000001, 0, 0x1 },
	{ 0x12b, 0x0001fffe, 1, 0x2 },
	{ 0x12b, 0x00000001, 0, 0x1 },
	{ 0x164, 0x0001fffe, 1, 0x4 },
	{ 0x164, 0x00000001, 0, 0x1 },
	{ 0x167, 0x0001fffe, 1, 0x4 },
	{ 0x167, 0x00000001, 0, 0x1 },
	{ 0x16a, 0x0001fffe, 1, 0x4 },
	{ 0x16a, 0x00000001, 0, 0x1 },
	{ 0x15e, 0x0001fffe, 1, 0x4 },
	{ 0x15e, 0x00000001, 0, 0x1 },
	{ 0x161, 0x0001fffe, 1, 0x4 },
	{ 0x161, 0x00000001, 0, 0x1 },
	{ 0x15b, 0x0001fffe, 1, 0x4 },
	{ 0x15b, 0x00000001, 0, 0x1 },
	{ 0x16d, 0x0001fffe, 1, 0x4 },
	{ 0x16d, 0x00000001, 0, 0x1 },
	{ 0x170, 0x0001fffe, 1, 0x2 },
	{ 0x170, 0x00000001, 0, 0x1 },
	{ 0x173, 0x0001fffe, 1, 0x2 },
	{ 0x173, 0x00000001, 0, 0x1 },
	{ 0x176, 0x0001fffe, 1, 0x2 },
	{ 0x176, 0x00000001, 0, 0x1 },
	{ 0x179, 0x0001fffe, 1, 0x2 },
	{ 0x179, 0x00000001, 0, 0x1 },
	{ 0x17c, 0x0001fffe, 1, 0x2 },
	{ 0x17c, 0x00000001, 0, 0x1 },
	{ 0x17f, 0x0001fffe, 1, 0x2 },
	{ 0x17f, 0x00000001, 0, 0x1 },
	{ 0xffffffff }
};

static struct reg lcac_cape_verde[] = {
	{ 0x98, 0x0001fffe, 1, 0x2 },
	{ 0x98, 0x00000001, 0, 0x1 },
	{ 0x104, 0x0001fffe, 1, 0x2 },
	{ 0x104, 0x00000001, 0, 0x1 },
	{ 0x110, 0x0001fffe, 1, 0x5 },
	{ 0x110, 0x00000001, 0, 0x1 },
	{ 0x14f, 0x0001fffe, 1, 0x5 },
	{ 0x14f, 0x00000001, 0, 0x1 },
	{ 0x8c, 0x0001fffe, 1, 0x5 },
	{ 0x8c, 0x00000001, 0, 0x1 },
	{ 0x143, 0x0001fffe, 1, 0x1 },
	{ 0x143, 0x00000001, 0, 0x1 },
	{ 0x9b, 0x0001fffe, 1, 0x2 },
	{ 0x9b, 0x00000001, 0, 0x1 },
	{ 0x107, 0x0001fffe, 1, 0x2 },
	{ 0x107, 0x00000001, 0, 0x1 },
	{ 0x113, 0x0001fffe, 1, 0x5 },
	{ 0x113, 0x00000001, 0, 0x1 },
	{ 0x152, 0x0001fffe, 1, 0x5 },
	{ 0x152, 0x00000001, 0, 0x1 },
	{ 0x8f, 0x0001fffe, 1, 0x1 },
	{ 0x8f, 0x00000001, 0, 0x1 },
	{ 0x146, 0x0001fffe, 1, 0x1 },
	{ 0x146, 0x00000001, 0, 0x1 },
	{ 0x11c, 0x0001fffe, 1, 0x2 },
	{ 0x11c, 0x00000001, 0, 0x1 },
	{ 0x11f, 0x0001fffe, 1, 0x2 },
	{ 0x11f, 0x00000001, 0, 0x1 },
	{ 0x164, 0x0001fffe, 1, 0x2 },
	{ 0x164, 0x00000001, 0, 0x1 },
	{ 0x167, 0x0001fffe, 1, 0x2 },
	{ 0x167, 0x00000001, 0, 0x1 },
	{ 0x16a, 0x0001fffe, 1, 0x2 },
	{ 0x16a, 0x00000001, 0, 0x1 },
	{ 0x15e, 0x0001fffe, 1, 0x2 },
	{ 0x15e, 0x00000001, 0, 0x1 },
	{ 0x161, 0x0001fffe, 1, 0x2 },
	{ 0x161, 0x00000001, 0, 0x1 },
	{ 0x15b, 0x0001fffe, 1, 0x2 },
	{ 0x15b, 0x00000001, 0, 0x1 },
	{ 0x16d, 0x0001fffe, 1, 0x2 },
	{ 0x16d, 0x00000001, 0, 0x1 },
	{ 0x170, 0x0001fffe, 1, 0x1 },
	{ 0x170, 0x00000001, 0, 0x1 },
	{ 0x173, 0x0001fffe, 1, 0x2 },
	{ 0x173, 0x00000001, 0, 0x1 },
	{ 0x176, 0x0001fffe, 1, 0x1 },
	{ 0x176, 0x00000001, 0, 0x1 },
	{ 0x179, 0x0001fffe, 1, 0x1 },
	{ 0x179, 0x00000001, 0, 0x1 },
	{ 0x17c, 0x0001fffe, 1, 0x1 },
	{ 0x17c, 0x00000001, 0, 0x1 },
	{ 0x17f, 0x0001fffe, 1, 0x1 },
	{ 0x17f, 0x00000001, 0, 0x1 },
	{ 0xffffffff }
};

static struct reg lcac_mars_pro[] = {
	{ 0x98, 0x0001fffe, 1, 0x2 },
	{ 0x98, 0x00000001, 0, 0x1 },
	{ 0x104, 0x0001fffe, 1, 0x2 },
	{ 0x104, 0x00000001, 0, 0x1 },
	{ 0x110, 0x0001fffe, 1, 0x6 },
	{ 0x110, 0x00000001, 0, 0x1 },
	{ 0x14f, 0x0001fffe, 1, 0x6 },
	{ 0x14f, 0x00000001, 0, 0x1 },
	{ 0x8c, 0x0001fffe, 1, 0x6 },
	{ 0x8c, 0x00000001, 0, 0x1 },
	{ 0x143, 0x0001fffe, 1, 0x2 },
	{ 0x143, 0x00000001, 0, 0x1 },
	{ 0x11c, 0x0001fffe, 1, 0x2 },
	{ 0x11c, 0x00000001, 0, 0x1 },
	{ 0x11f, 0x0001fffe, 1, 0x2 },
	{ 0x11f, 0x00000001, 0, 0x1 },
	{ 0x164, 0x0001fffe, 1, 0x1 },
	{ 0x164, 0x00000001, 0, 0x1 },
	{ 0x167, 0x0001fffe, 1, 0x1 },
	{ 0x167, 0x00000001, 0, 0x1 },
	{ 0x16a, 0x0001fffe, 1, 0x1 },
	{ 0x16a, 0x00000001, 0, 0x1 },
	{ 0x15e, 0x0001fffe, 1, 0x1 },
	{ 0x15e, 0x00000001, 0, 0x1 },
	{ 0x161, 0x0001fffe, 1, 0x1 },
	{ 0x161, 0x00000001, 0, 0x1 },
	{ 0x15b, 0x0001fffe, 1, 0x1 },
	{ 0x15b, 0x00000001, 0, 0x1 },
	{ 0x16d, 0x0001fffe, 1, 0x2 },
	{ 0x16d, 0x00000001, 0, 0x1 },
	{ 0x170, 0x0001fffe, 1, 0x1 },
	{ 0x170, 0x00000001, 0, 0x1 },
	{ 0x173, 0x0001fffe, 1, 0x1 },
	{ 0x173, 0x00000001, 0, 0x1 },
	{ 0x176, 0x0001fffe, 1, 0x1 },
	{ 0x176, 0x00000001, 0, 0x1 },
	{ 0x179, 0x0001fffe, 1, 0x1 },
	{ 0x179, 0x00000001, 0, 0x1 },
	{ 0x17c, 0x0001fffe, 1, 0x1 },
	{ 0x17c, 0x00000001, 0, 0x1 },
	{ 0x17f, 0x0001fffe, 1, 0x1 },
	{ 0x17f, 0x00000001, 0, 0x1 },
	{ 0xffffffff }
};

static struct reg lcac_oland[] = {
	{ 0x98, 0x0001fffe, 1, 0x2 },
	{ 0x98, 0x00000001, 0, 0x1 },
	{ 0x104, 0x0001fffe, 1, 0x2 },
	{ 0x104, 0x00000001, 0, 0x1 },
	{ 0x110, 0x0001fffe, 1, 0x6 },
	{ 0x110, 0x00000001, 0, 0x1 },
	{ 0x14f, 0x0001fffe, 1, 0x6 },
	{ 0x14f, 0x00000001, 0, 0x1 },
	{ 0x8c, 0x0001fffe, 1, 0x6 },
	{ 0x8c, 0x00000001, 0, 0x1 },
	{ 0x143, 0x0001fffe, 1, 0x4 },
	{ 0x143, 0x00000001, 0, 0x1 },
	{ 0x11c, 0x0001fffe, 1, 0x2 },
	{ 0x11c, 0x00000001, 0, 0x1 },
	{ 0x11f, 0x0001fffe, 1, 0x2 },
	{ 0x11f, 0x00000001, 0, 0x1 },
	{ 0x164, 0x0001fffe, 1, 0x1 },
	{ 0x164, 0x00000001, 0, 0x1 },
	{ 0x167, 0x0001fffe, 1, 0x1 },
	{ 0x167, 0x00000001, 0, 0x1 },
	{ 0x16a, 0x0001fffe, 1, 0x1 },
	{ 0x16a, 0x00000001, 0, 0x1 },
	{ 0x15e, 0x0001fffe, 1, 0x1 },
	{ 0x15e, 0x00000001, 0, 0x1 },
	{ 0x161, 0x0001fffe, 1, 0x1 },
	{ 0x161, 0x00000001, 0, 0x1 },
	{ 0x15b, 0x0001fffe, 1, 0x1 },
	{ 0x15b, 0x00000001, 0, 0x1 },
	{ 0x16d, 0x0001fffe, 1, 0x2 },
	{ 0x16d, 0x00000001, 0, 0x1 },
	{ 0x170, 0x0001fffe, 1, 0x1 },
	{ 0x170, 0x00000001, 0, 0x1 },
	{ 0x173, 0x0001fffe, 1, 0x1 },
	{ 0x173, 0x00000001, 0, 0x1 },
	{ 0x176, 0x0001fffe, 1, 0x1 },
	{ 0x176, 0x00000001, 0, 0x1 },
	{ 0x179, 0x0001fffe, 1, 0x1 },
	{ 0x179, 0x00000001, 0, 0x1 },
	{ 0x17c, 0x0001fffe, 1, 0x1 },
	{ 0x17c, 0x00000001, 0, 0x1 },
	{ 0x17f, 0x0001fffe, 1, 0x1 },
	{ 0x17f, 0x00000001, 0, 0x1 },
	{ 0xffffffff }
};

static struct reg cac_weights_tahiti[] = {
	{ 0x0, 0x0000ffff, 0, 0xc },
	{ 0x0, 0xffff0000, 16, 0x0 },
	{ 0x1, 0x0000ffff, 0, 0x101 },
	{ 0x1, 0xffff0000, 16, 0xc },
	{ 0x2, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0xffff0000, 16, 0x0 },
	{ 0x4, 0x0000ffff, 0, 0x0 },
	{ 0x4, 0xffff0000, 16, 0x0 },
	{ 0x5, 0x0000ffff, 0, 0x8fc },
	{ 0x5, 0xffff0000, 16, 0x0 },
	{ 0x6, 0x0000ffff, 0, 0x95 },
	{ 0x6, 0xffff0000, 16, 0x34e },
	{ 0x18f, 0x0000ffff, 0, 0x1a1 },
	{ 0x7, 0x0000ffff, 0, 0xda },
	{ 0x7, 0xffff0000, 16, 0x0 },
	{ 0x8, 0x0000ffff, 0, 0x0 },
	{ 0x8, 0xffff0000, 16, 0x46 },
	{ 0x9, 0x0000ffff, 0, 0x0 },
	{ 0xa, 0x0000ffff, 0, 0x208 },
	{ 0xb, 0x0000ffff, 0, 0xe7 },
	{ 0xb, 0xffff0000, 16, 0x948 },
	{ 0xc, 0x0000ffff, 0, 0x0 },
	{ 0xd, 0x0000ffff, 0, 0x0 },
	{ 0xd, 0xffff0000, 16, 0x0 },
	{ 0xe, 0x0000ffff, 0, 0x0 },
	{ 0xf, 0x0000ffff, 0, 0x0 },
	{ 0xf, 0xffff0000, 16, 0x0 },
	{ 0x10, 0x0000ffff, 0, 0x0 },
	{ 0x10, 0xffff0000, 16, 0x0 },
	{ 0x11, 0x0000ffff, 0, 0x167 },
	{ 0x11, 0xffff0000, 16, 0x0 },
	{ 0x12, 0x0000ffff, 0, 0x0 },
	{ 0x13, 0x0000ffff, 0, 0x0 },
	{ 0x13, 0xffff0000, 16, 0x35 },
	{ 0x14, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0xffff0000, 16, 0x2 },
	{ 0x4e, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0x0000ffff, 0, 0x31 },
	{ 0x16, 0xffff0000, 16, 0x0 },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0x0 },
	{ 0x1a, 0xffff0000, 16, 0x0 },
	{ 0x1b, 0x0000ffff, 0, 0x0 },
	{ 0x1b, 0xffff0000, 16, 0x0 },
	{ 0x1c, 0x0000ffff, 0, 0x0 },
	{ 0x1c, 0xffff0000, 16, 0x0 },
	{ 0x1d, 0x0000ffff, 0, 0x0 },
	{ 0x1d, 0xffff0000, 16, 0x0 },
	{ 0x1e, 0x0000ffff, 0, 0x0 },
	{ 0x1e, 0xffff0000, 16, 0x0 },
	{ 0x1f, 0x0000ffff, 0, 0x0 },
	{ 0x1f, 0xffff0000, 16, 0x0 },
	{ 0x20, 0x0000ffff, 0, 0x0 },
	{ 0x6d, 0x0000ffff, 0, 0x18e },
	{ 0xffffffff }
};

struct reg cac_weights_pitcairn[] = {
	{ 0x0, 0x0000ffff, 0, 0x8a },
	{ 0x0, 0xffff0000, 16, 0x0 },
	{ 0x1, 0x0000ffff, 0, 0x0 },
	{ 0x1, 0xffff0000, 16, 0x24d },
	{ 0x2, 0x0000ffff, 0, 0x19 },
	{ 0x3, 0x0000ffff, 0, 0x118 },
	{ 0x3, 0xffff0000, 16, 0x0 },
	{ 0x4, 0x0000ffff, 0, 0x76 },
	{ 0x4, 0xffff0000, 16, 0x0 },
	{ 0x5, 0x0000ffff, 0, 0xc11 },
	{ 0x5, 0xffff0000, 16, 0x7f3 },
	{ 0x6, 0x0000ffff, 0, 0x403 },
	{ 0x6, 0xffff0000, 16, 0x367 },
	{ 0x18f, 0x0000ffff, 0, 0x4c9 },
	{ 0x7, 0x0000ffff, 0, 0x0 },
	{ 0x7, 0xffff0000, 16, 0x0 },
	{ 0x8, 0x0000ffff, 0, 0x0 },
	{ 0x8, 0xffff0000, 16, 0x45d },
	{ 0x9, 0x0000ffff, 0, 0x36d },
	{ 0xa, 0x0000ffff, 0, 0x534 },
	{ 0xb, 0x0000ffff, 0, 0x5da },
	{ 0xb, 0xffff0000, 16, 0x880 },
	{ 0xc, 0x0000ffff, 0, 0x201 },
	{ 0xd, 0x0000ffff, 0, 0x0 },
	{ 0xd, 0xffff0000, 16, 0x0 },
	{ 0xe, 0x0000ffff, 0, 0x9f },
	{ 0xf, 0x0000ffff, 0, 0x1f },
	{ 0xf, 0xffff0000, 16, 0x0 },
	{ 0x10, 0x0000ffff, 0, 0x0 },
	{ 0x10, 0xffff0000, 16, 0x0 },
	{ 0x11, 0x0000ffff, 0, 0x5de },
	{ 0x11, 0xffff0000, 16, 0x0 },
	{ 0x12, 0x0000ffff, 0, 0x7b },
	{ 0x13, 0x0000ffff, 0, 0x0 },
	{ 0x13, 0xffff0000, 16, 0x13 },
	{ 0x14, 0x0000ffff, 0, 0xf9 },
	{ 0x15, 0x0000ffff, 0, 0x66 },
	{ 0x15, 0xffff0000, 16, 0x0 },
	{ 0x4e, 0x0000ffff, 0, 0x13 },
	{ 0x16, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0xffff0000, 16, 0x0 },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0x0 },
	{ 0x1a, 0xffff0000, 16, 0x0 },
	{ 0x1b, 0x0000ffff, 0, 0x0 },
	{ 0x1b, 0xffff0000, 16, 0x0 },
	{ 0x1c, 0x0000ffff, 0, 0x0 },
	{ 0x1c, 0xffff0000, 16, 0x0 },
	{ 0x1d, 0x0000ffff, 0, 0x0 },
	{ 0x1d, 0xffff0000, 16, 0x0 },
	{ 0x1e, 0x0000ffff, 0, 0x0 },
	{ 0x1e, 0xffff0000, 16, 0x0 },
	{ 0x1f, 0x0000ffff, 0, 0x0 },
	{ 0x1f, 0xffff0000, 16, 0x0 },
	{ 0x20, 0x0000ffff, 0, 0x0 },
	{ 0x6d, 0x0000ffff, 0, 0x186 },
	{ 0xffffffff }
};

static struct reg cac_weights_cape_verde_pro[] = {
	{ 0x0, 0x0000ffff, 0, 0x82 },
	{ 0x0, 0xffff0000, 16, 0x4f },
	{ 0x1, 0x0000ffff, 0, 0x153 },
	{ 0x1, 0xffff0000, 16, 0x52 },
	{ 0x2, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0x0000ffff, 0, 0x135 },
	{ 0x3, 0xffff0000, 16, 0x4f },
	{ 0x4, 0x0000ffff, 0, 0x135 },
	{ 0x4, 0xffff0000, 16, 0xac },
	{ 0x5, 0x0000ffff, 0, 0x118 },
	{ 0x5, 0xffff0000, 16, 0xbe },
	{ 0x6, 0x0000ffff, 0, 0x110 },
	{ 0x6, 0xffff0000, 16, 0x4cd },
	{ 0x18f, 0x0000ffff, 0, 0x30 },
	{ 0x7, 0x0000ffff, 0, 0x37 },
	{ 0x7, 0xffff0000, 16, 0x27 },
	{ 0x8, 0x0000ffff, 0, 0xc3 },
	{ 0x8, 0xffff0000, 16, 0x35 },
	{ 0x9, 0x0000ffff, 0, 0x28 },
	{ 0xa, 0x0000ffff, 0, 0x26c },
	{ 0xb, 0x0000ffff, 0, 0x3b2 },
	{ 0xb, 0xffff0000, 16, 0x99d },
	{ 0xc, 0x0000ffff, 0, 0xa3f },
	{ 0xd, 0x0000ffff, 0, 0xa },
	{ 0xd, 0xffff0000, 16, 0xa },
	{ 0xe, 0x0000ffff, 0, 0x5 },
	{ 0xf, 0x0000ffff, 0, 0x3 },
	{ 0xf, 0xffff0000, 16, 0x0 },
	{ 0x10, 0x0000ffff, 0, 0x1 },
	{ 0x10, 0xffff0000, 16, 0x1 },
	{ 0x11, 0x0000ffff, 0, 0x5 },
	{ 0x11, 0xffff0000, 16, 0x15 },
	{ 0x12, 0x0000ffff, 0, 0x34 },
	{ 0x13, 0x0000ffff, 0, 0x4 },
	{ 0x13, 0xffff0000, 16, 0x4 },
	{ 0x14, 0x0000ffff, 0, 0x315 },
	{ 0x15, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0xffff0000, 16, 0x6 },
	{ 0x4e, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0x0000ffff, 0, 0x30 },
	{ 0x16, 0xffff0000, 16, 0x7a },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0 },
	{ 0x1a, 0xffff0000, 16, 0 },
	{ 0x1b, 0x0000ffff, 0, 0 },
	{ 0x1b, 0xffff0000, 16, 0 },
	{ 0x1c, 0x0000ffff, 0, 0 },
	{ 0x1c, 0xffff0000, 16, 0 },
	{ 0x1d, 0x0000ffff, 0, 0 },
	{ 0x1d, 0xffff0000, 16, 0 },
	{ 0x1e, 0x0000ffff, 0, 0 },
	{ 0x1e, 0xffff0000, 16, 0 },
	{ 0x1f, 0x0000ffff, 0, 0 },
	{ 0x1f, 0xffff0000, 16, 0 },
	{ 0x20, 0x0000ffff, 0, 0 },
	{ 0x6d, 0x0000ffff, 0, 0x100 },
	{ 0xffffffff }
};

static struct reg cac_weights_heathrow[] = {
	{ 0x0, 0x0000ffff, 0, 0x82 },
	{ 0x0, 0xffff0000, 16, 0x4f },
	{ 0x1, 0x0000ffff, 0, 0x153 },
	{ 0x1, 0xffff0000, 16, 0x52 },
	{ 0x2, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0x0000ffff, 0, 0x135 },
	{ 0x3, 0xffff0000, 16, 0x4f },
	{ 0x4, 0x0000ffff, 0, 0x135 },
	{ 0x4, 0xffff0000, 16, 0xac },
	{ 0x5, 0x0000ffff, 0, 0x118 },
	{ 0x5, 0xffff0000, 16, 0xbe },
	{ 0x6, 0x0000ffff, 0, 0x110 },
	{ 0x6, 0xffff0000, 16, 0x4cd },
	{ 0x18f, 0x0000ffff, 0, 0x30 },
	{ 0x7, 0x0000ffff, 0, 0x37 },
	{ 0x7, 0xffff0000, 16, 0x27 },
	{ 0x8, 0x0000ffff, 0, 0xc3 },
	{ 0x8, 0xffff0000, 16, 0x35 },
	{ 0x9, 0x0000ffff, 0, 0x28 },
	{ 0xa, 0x0000ffff, 0, 0x26c },
	{ 0xb, 0x0000ffff, 0, 0x3b2 },
	{ 0xb, 0xffff0000, 16, 0x99d },
	{ 0xc, 0x0000ffff, 0, 0xa3f },
	{ 0xd, 0x0000ffff, 0, 0xa },
	{ 0xd, 0xffff0000, 16, 0xa },
	{ 0xe, 0x0000ffff, 0, 0x5 },
	{ 0xf, 0x0000ffff, 0, 0x3 },
	{ 0xf, 0xffff0000, 16, 0x0 },
	{ 0x10, 0x0000ffff, 0, 0x1 },
	{ 0x10, 0xffff0000, 16, 0x1 },
	{ 0x11, 0x0000ffff, 0, 0x5 },
	{ 0x11, 0xffff0000, 16, 0x15 },
	{ 0x12, 0x0000ffff, 0, 0x34 },
	{ 0x13, 0x0000ffff, 0, 0x4 },
	{ 0x13, 0xffff0000, 16, 0x4 },
	{ 0x14, 0x0000ffff, 0, 0x362 },
	{ 0x15, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0xffff0000, 16, 0x6 },
	{ 0x4e, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0x0000ffff, 0, 0x30 },
	{ 0x16, 0xffff0000, 16, 0x7a },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0 },
	{ 0x1a, 0xffff0000, 16, 0 },
	{ 0x1b, 0x0000ffff, 0, 0 },
	{ 0x1b, 0xffff0000, 16, 0 },
	{ 0x1c, 0x0000ffff, 0, 0 },
	{ 0x1c, 0xffff0000, 16, 0 },
	{ 0x1d, 0x0000ffff, 0, 0 },
	{ 0x1d, 0xffff0000, 16, 0 },
	{ 0x1e, 0x0000ffff, 0, 0 },
	{ 0x1e, 0xffff0000, 16, 0 },
	{ 0x1f, 0x0000ffff, 0, 0 },
	{ 0x1f, 0xffff0000, 16, 0 },
	{ 0x20, 0x0000ffff, 0, 0 },
	{ 0x6d, 0x0000ffff, 0, 0x100 },
	{ 0xffffffff }
};

static struct reg cac_weights_chelsea_xt[] = {
	{ 0x0, 0x0000ffff, 0, 0x82 },
	{ 0x0, 0xffff0000, 16, 0x4f },
	{ 0x1, 0x0000ffff, 0, 0x153 },
	{ 0x1, 0xffff0000, 16, 0x52 },
	{ 0x2, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0x0000ffff, 0, 0x135 },
	{ 0x3, 0xffff0000, 16, 0x4f },
	{ 0x4, 0x0000ffff, 0, 0x135 },
	{ 0x4, 0xffff0000, 16, 0xac },
	{ 0x5, 0x0000ffff, 0, 0x118 },
	{ 0x5, 0xffff0000, 16, 0xbe },
	{ 0x6, 0x0000ffff, 0, 0x110 },
	{ 0x6, 0xffff0000, 16, 0x4cd },
	{ 0x18f, 0x0000ffff, 0, 0x30 },
	{ 0x7, 0x0000ffff, 0, 0x37 },
	{ 0x7, 0xffff0000, 16, 0x27 },
	{ 0x8, 0x0000ffff, 0, 0xc3 },
	{ 0x8, 0xffff0000, 16, 0x35 },
	{ 0x9, 0x0000ffff, 0, 0x28 },
	{ 0xa, 0x0000ffff, 0, 0x26c },
	{ 0xb, 0x0000ffff, 0, 0x3b2 },
	{ 0xb, 0xffff0000, 16, 0x99d },
	{ 0xc, 0x0000ffff, 0, 0xa3f },
	{ 0xd, 0x0000ffff, 0, 0xa },
	{ 0xd, 0xffff0000, 16, 0xa },
	{ 0xe, 0x0000ffff, 0, 0x5 },
	{ 0xf, 0x0000ffff, 0, 0x3 },
	{ 0xf, 0xffff0000, 16, 0x0 },
	{ 0x10, 0x0000ffff, 0, 0x1 },
	{ 0x10, 0xffff0000, 16, 0x1 },
	{ 0x11, 0x0000ffff, 0, 0x5 },
	{ 0x11, 0xffff0000, 16, 0x15 },
	{ 0x12, 0x0000ffff, 0, 0x34 },
	{ 0x13, 0x0000ffff, 0, 0x4 },
	{ 0x13, 0xffff0000, 16, 0x4 },
	{ 0x14, 0x0000ffff, 0, 0x30a },
	{ 0x15, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0xffff0000, 16, 0x6 },
	{ 0x4e, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0x0000ffff, 0, 0x30 },
	{ 0x16, 0xffff0000, 16, 0x7a },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0 },
	{ 0x1a, 0xffff0000, 16, 0 },
	{ 0x1b, 0x0000ffff, 0, 0 },
	{ 0x1b, 0xffff0000, 16, 0 },
	{ 0x1c, 0x0000ffff, 0, 0 },
	{ 0x1c, 0xffff0000, 16, 0 },
	{ 0x1d, 0x0000ffff, 0, 0 },
	{ 0x1d, 0xffff0000, 16, 0 },
	{ 0x1e, 0x0000ffff, 0, 0 },
	{ 0x1e, 0xffff0000, 16, 0 },
	{ 0x1f, 0x0000ffff, 0, 0 },
	{ 0x1f, 0xffff0000, 16, 0 },
	{ 0x20, 0x0000ffff, 0, 0 },
	{ 0x6d, 0x0000ffff, 0, 0x100 },
	{ 0xffffffff }
};

static struct reg cac_weights_chelsea_pro[] = {
	{ 0x0, 0x0000ffff, 0, 0x82 },
	{ 0x0, 0xffff0000, 16, 0x4f },
	{ 0x1, 0x0000ffff, 0, 0x153 },
	{ 0x1, 0xffff0000, 16, 0x52 },
	{ 0x2, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0x0000ffff, 0, 0x135 },
	{ 0x3, 0xffff0000, 16, 0x4f },
	{ 0x4, 0x0000ffff, 0, 0x135 },
	{ 0x4, 0xffff0000, 16, 0xac },
	{ 0x5, 0x0000ffff, 0, 0x118 },
	{ 0x5, 0xffff0000, 16, 0xbe },
	{ 0x6, 0x0000ffff, 0, 0x110 },
	{ 0x6, 0xffff0000, 16, 0x4cd },
	{ 0x18f, 0x0000ffff, 0, 0x30 },
	{ 0x7, 0x0000ffff, 0, 0x37 },
	{ 0x7, 0xffff0000, 16, 0x27 },
	{ 0x8, 0x0000ffff, 0, 0xc3 },
	{ 0x8, 0xffff0000, 16, 0x35 },
	{ 0x9, 0x0000ffff, 0, 0x28 },
	{ 0xa, 0x0000ffff, 0, 0x26c },
	{ 0xb, 0x0000ffff, 0, 0x3b2 },
	{ 0xb, 0xffff0000, 16, 0x99d },
	{ 0xc, 0x0000ffff, 0, 0xa3f },
	{ 0xd, 0x0000ffff, 0, 0xa },
	{ 0xd, 0xffff0000, 16, 0xa },
	{ 0xe, 0x0000ffff, 0, 0x5 },
	{ 0xf, 0x0000ffff, 0, 0x3 },
	{ 0xf, 0xffff0000, 16, 0x0 },
	{ 0x10, 0x0000ffff, 0, 0x1 },
	{ 0x10, 0xffff0000, 16, 0x1 },
	{ 0x11, 0x0000ffff, 0, 0x5 },
	{ 0x11, 0xffff0000, 16, 0x15 },
	{ 0x12, 0x0000ffff, 0, 0x34 },
	{ 0x13, 0x0000ffff, 0, 0x4 },
	{ 0x13, 0xffff0000, 16, 0x4 },
	{ 0x14, 0x0000ffff, 0, 0x2bd },
	{ 0x15, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0xffff0000, 16, 0x6 },
	{ 0x4e, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0x0000ffff, 0, 0x30 },
	{ 0x16, 0xffff0000, 16, 0x7a },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0 },
	{ 0x1a, 0xffff0000, 16, 0 },
	{ 0x1b, 0x0000ffff, 0, 0 },
	{ 0x1b, 0xffff0000, 16, 0 },
	{ 0x1c, 0x0000ffff, 0, 0 },
	{ 0x1c, 0xffff0000, 16, 0 },
	{ 0x1d, 0x0000ffff, 0, 0 },
	{ 0x1d, 0xffff0000, 16, 0 },
	{ 0x1e, 0x0000ffff, 0, 0 },
	{ 0x1e, 0xffff0000, 16, 0 },
	{ 0x1f, 0x0000ffff, 0, 0 },
	{ 0x1f, 0xffff0000, 16, 0 },
	{ 0x20, 0x0000ffff, 0, 0 },
	{ 0x6d, 0x0000ffff, 0, 0x100 },
	{ 0xffffffff }
};

static struct reg cac_weights_cape_verde[] = {
	{ 0x0, 0x0000ffff, 0, 0x82 },
	{ 0x0, 0xffff0000, 16, 0x4f },
	{ 0x1, 0x0000ffff, 0, 0x153 },
	{ 0x1, 0xffff0000, 16, 0x52 },
	{ 0x2, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0x0000ffff, 0, 0x135 },
	{ 0x3, 0xffff0000, 16, 0x4f },
	{ 0x4, 0x0000ffff, 0, 0x135 },
	{ 0x4, 0xffff0000, 16, 0xac },
	{ 0x5, 0x0000ffff, 0, 0x118 },
	{ 0x5, 0xffff0000, 16, 0xbe },
	{ 0x6, 0x0000ffff, 0, 0x110 },
	{ 0x6, 0xffff0000, 16, 0x4cd },
	{ 0x18f, 0x0000ffff, 0, 0x30 },
	{ 0x7, 0x0000ffff, 0, 0x37 },
	{ 0x7, 0xffff0000, 16, 0x27 },
	{ 0x8, 0x0000ffff, 0, 0xc3 },
	{ 0x8, 0xffff0000, 16, 0x35 },
	{ 0x9, 0x0000ffff, 0, 0x28 },
	{ 0xa, 0x0000ffff, 0, 0x26c },
	{ 0xb, 0x0000ffff, 0, 0x3b2 },
	{ 0xb, 0xffff0000, 16, 0x99d },
	{ 0xc, 0x0000ffff, 0, 0xa3f },
	{ 0xd, 0x0000ffff, 0, 0xa },
	{ 0xd, 0xffff0000, 16, 0xa },
	{ 0xe, 0x0000ffff, 0, 0x5 },
	{ 0xf, 0x0000ffff, 0, 0x3 },
	{ 0xf, 0xffff0000, 16, 0x0 },
	{ 0x10, 0x0000ffff, 0, 0x1 },
	{ 0x10, 0xffff0000, 16, 0x1 },
	{ 0x11, 0x0000ffff, 0, 0x5 },
	{ 0x11, 0xffff0000, 16, 0x15 },
	{ 0x12, 0x0000ffff, 0, 0x34 },
	{ 0x13, 0x0000ffff, 0, 0x4 },
	{ 0x13, 0xffff0000, 16, 0x4 },
	{ 0x14, 0x0000ffff, 0, 0x3ba },
	{ 0x15, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0xffff0000, 16, 0x6 },
	{ 0x4e, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0x0000ffff, 0, 0x30 },
	{ 0x16, 0xffff0000, 16, 0x7a },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0 },
	{ 0x1a, 0xffff0000, 16, 0 },
	{ 0x1b, 0x0000ffff, 0, 0 },
	{ 0x1b, 0xffff0000, 16, 0 },
	{ 0x1c, 0x0000ffff, 0, 0 },
	{ 0x1c, 0xffff0000, 16, 0 },
	{ 0x1d, 0x0000ffff, 0, 0 },
	{ 0x1d, 0xffff0000, 16, 0 },
	{ 0x1e, 0x0000ffff, 0, 0 },
	{ 0x1e, 0xffff0000, 16, 0 },
	{ 0x1f, 0x0000ffff, 0, 0 },
	{ 0x1f, 0xffff0000, 16, 0 },
	{ 0x20, 0x0000ffff, 0, 0 },
	{ 0x6d, 0x0000ffff, 0, 0x100 },
	{ 0xffffffff }
};

static struct reg cac_weights_mars_pro[] = {
	{ 0x0, 0x0000ffff, 0, 0x43 },
	{ 0x0, 0xffff0000, 16, 0x29 },
	{ 0x1, 0x0000ffff, 0, 0xaf },
	{ 0x1, 0xffff0000, 16, 0x2a },
	{ 0x2, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0x0000ffff, 0, 0xa0 },
	{ 0x3, 0xffff0000, 16, 0x29 },
	{ 0x4, 0x0000ffff, 0, 0xa0 },
	{ 0x4, 0xffff0000, 16, 0x59 },
	{ 0x5, 0x0000ffff, 0, 0x1a5 },
	{ 0x5, 0xffff0000, 16, 0x1d6 },
	{ 0x6, 0x0000ffff, 0, 0x2a3 },
	{ 0x6, 0xffff0000, 16, 0x8fd },
	{ 0x18f, 0x0000ffff, 0, 0x76 },
	{ 0x7, 0x0000ffff, 0, 0x8a },
	{ 0x7, 0xffff0000, 16, 0xa3 },
	{ 0x8, 0x0000ffff, 0, 0x71 },
	{ 0x8, 0xffff0000, 16, 0x36 },
	{ 0x9, 0x0000ffff, 0, 0xa6 },
	{ 0xa, 0x0000ffff, 0, 0x81 },
	{ 0xb, 0x0000ffff, 0, 0x3d2 },
	{ 0xb, 0xffff0000, 16, 0x27c },
	{ 0xc, 0x0000ffff, 0, 0xa96 },
	{ 0xd, 0x0000ffff, 0, 0x5 },
	{ 0xd, 0xffff0000, 16, 0x5 },
	{ 0xe, 0x0000ffff, 0, 0xb },
	{ 0xf, 0x0000ffff, 0, 0x3 },
	{ 0xf, 0xffff0000, 16, 0x2 },
	{ 0x10, 0x0000ffff, 0, 0x1 },
	{ 0x10, 0xffff0000, 16, 0x4 },
	{ 0x11, 0x0000ffff, 0, 0x15 },
	{ 0x11, 0xffff0000, 16, 0x7 },
	{ 0x12, 0x0000ffff, 0, 0x36 },
	{ 0x13, 0x0000ffff, 0, 0x10 },
	{ 0x13, 0xffff0000, 16, 0x10 },
	{ 0x14, 0x0000ffff, 0, 0x2 },
	{ 0x15, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0xffff0000, 16, 0x6 },
	{ 0x4e, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0x0000ffff, 0, 0x32 },
	{ 0x16, 0xffff0000, 16, 0x7e },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0x280 },
	{ 0x1a, 0xffff0000, 16, 0x7 },
	{ 0x1b, 0x0000ffff, 0, 0x0 },
	{ 0x1b, 0xffff0000, 16, 0x0 },
	{ 0x1c, 0x0000ffff, 0, 0x3c },
	{ 0x1c, 0xffff0000, 16, 0x203 },
	{ 0x1d, 0x0000ffff, 0, 0x0 },
	{ 0x1d, 0xffff0000, 16, 0x0 },
	{ 0x1e, 0x0000ffff, 0, 0 },
	{ 0x1e, 0xffff0000, 16, 0 },
	{ 0x1f, 0x0000ffff, 0, 0 },
	{ 0x1f, 0xffff0000, 16, 0 },
	{ 0x20, 0x0000ffff, 0, 0 },
	{ 0x6d, 0x0000ffff, 0, 0xb4 },
	{ 0xffffffff }
};

static struct reg cac_weights_mars_xt[] = {
	{ 0x0, 0x0000ffff, 0, 0x43 },
	{ 0x0, 0xffff0000, 16, 0x29 },
	{ 0x1, 0x0000ffff, 0, 0xaf },
	{ 0x1, 0xffff0000, 16, 0x2a },
	{ 0x2, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0x0000ffff, 0, 0xa0 },
	{ 0x3, 0xffff0000, 16, 0x29 },
	{ 0x4, 0x0000ffff, 0, 0xa0 },
	{ 0x4, 0xffff0000, 16, 0x59 },
	{ 0x5, 0x0000ffff, 0, 0x1a5 },
	{ 0x5, 0xffff0000, 16, 0x1d6 },
	{ 0x6, 0x0000ffff, 0, 0x2a3 },
	{ 0x6, 0xffff0000, 16, 0x8fd },
	{ 0x18f, 0x0000ffff, 0, 0x76 },
	{ 0x7, 0x0000ffff, 0, 0x8a },
	{ 0x7, 0xffff0000, 16, 0xa3 },
	{ 0x8, 0x0000ffff, 0, 0x71 },
	{ 0x8, 0xffff0000, 16, 0x36 },
	{ 0x9, 0x0000ffff, 0, 0xa6 },
	{ 0xa, 0x0000ffff, 0, 0x81 },
	{ 0xb, 0x0000ffff, 0, 0x3d2 },
	{ 0xb, 0xffff0000, 16, 0x27c },
	{ 0xc, 0x0000ffff, 0, 0xa96 },
	{ 0xd, 0x0000ffff, 0, 0x5 },
	{ 0xd, 0xffff0000, 16, 0x5 },
	{ 0xe, 0x0000ffff, 0, 0xb },
	{ 0xf, 0x0000ffff, 0, 0x3 },
	{ 0xf, 0xffff0000, 16, 0x2 },
	{ 0x10, 0x0000ffff, 0, 0x1 },
	{ 0x10, 0xffff0000, 16, 0x4 },
	{ 0x11, 0x0000ffff, 0, 0x15 },
	{ 0x11, 0xffff0000, 16, 0x7 },
	{ 0x12, 0x0000ffff, 0, 0x36 },
	{ 0x13, 0x0000ffff, 0, 0x10 },
	{ 0x13, 0xffff0000, 16, 0x10 },
	{ 0x14, 0x0000ffff, 0, 0x60 },
	{ 0x15, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0xffff0000, 16, 0x6 },
	{ 0x4e, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0x0000ffff, 0, 0x32 },
	{ 0x16, 0xffff0000, 16, 0x7e },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0x280 },
	{ 0x1a, 0xffff0000, 16, 0x7 },
	{ 0x1b, 0x0000ffff, 0, 0x0 },
	{ 0x1b, 0xffff0000, 16, 0x0 },
	{ 0x1c, 0x0000ffff, 0, 0x3c },
	{ 0x1c, 0xffff0000, 16, 0x203 },
	{ 0x1d, 0x0000ffff, 0, 0x0 },
	{ 0x1d, 0xffff0000, 16, 0x0 },
	{ 0x1e, 0x0000ffff, 0, 0 },
	{ 0x1e, 0xffff0000, 16, 0 },
	{ 0x1f, 0x0000ffff, 0, 0 },
	{ 0x1f, 0xffff0000, 16, 0 },
	{ 0x20, 0x0000ffff, 0, 0 },
	{ 0x6d, 0x0000ffff, 0, 0xb4 },
	{ 0xffffffff }
};

static struct reg cac_weights_oland_pro[] = {
	{ 0x0, 0x0000ffff, 0, 0x43 },
	{ 0x0, 0xffff0000, 16, 0x29 },
	{ 0x1, 0x0000ffff, 0, 0xaf },
	{ 0x1, 0xffff0000, 16, 0x2a },
	{ 0x2, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0x0000ffff, 0, 0xa0 },
	{ 0x3, 0xffff0000, 16, 0x29 },
	{ 0x4, 0x0000ffff, 0, 0xa0 },
	{ 0x4, 0xffff0000, 16, 0x59 },
	{ 0x5, 0x0000ffff, 0, 0x1a5 },
	{ 0x5, 0xffff0000, 16, 0x1d6 },
	{ 0x6, 0x0000ffff, 0, 0x2a3 },
	{ 0x6, 0xffff0000, 16, 0x8fd },
	{ 0x18f, 0x0000ffff, 0, 0x76 },
	{ 0x7, 0x0000ffff, 0, 0x8a },
	{ 0x7, 0xffff0000, 16, 0xa3 },
	{ 0x8, 0x0000ffff, 0, 0x71 },
	{ 0x8, 0xffff0000, 16, 0x36 },
	{ 0x9, 0x0000ffff, 0, 0xa6 },
	{ 0xa, 0x0000ffff, 0, 0x81 },
	{ 0xb, 0x0000ffff, 0, 0x3d2 },
	{ 0xb, 0xffff0000, 16, 0x27c },
	{ 0xc, 0x0000ffff, 0, 0xa96 },
	{ 0xd, 0x0000ffff, 0, 0x5 },
	{ 0xd, 0xffff0000, 16, 0x5 },
	{ 0xe, 0x0000ffff, 0, 0xb },
	{ 0xf, 0x0000ffff, 0, 0x3 },
	{ 0xf, 0xffff0000, 16, 0x2 },
	{ 0x10, 0x0000ffff, 0, 0x1 },
	{ 0x10, 0xffff0000, 16, 0x4 },
	{ 0x11, 0x0000ffff, 0, 0x15 },
	{ 0x11, 0xffff0000, 16, 0x7 },
	{ 0x12, 0x0000ffff, 0, 0x36 },
	{ 0x13, 0x0000ffff, 0, 0x10 },
	{ 0x13, 0xffff0000, 16, 0x10 },
	{ 0x14, 0x0000ffff, 0, 0x90 },
	{ 0x15, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0xffff0000, 16, 0x6 },
	{ 0x4e, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0x0000ffff, 0, 0x32 },
	{ 0x16, 0xffff0000, 16, 0x7e },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0x280 },
	{ 0x1a, 0xffff0000, 16, 0x7 },
	{ 0x1b, 0x0000ffff, 0, 0x0 },
	{ 0x1b, 0xffff0000, 16, 0x0 },
	{ 0x1c, 0x0000ffff, 0, 0x3c },
	{ 0x1c, 0xffff0000, 16, 0x203 },
	{ 0x1d, 0x0000ffff, 0, 0x0 },
	{ 0x1d, 0xffff0000, 16, 0x0 },
	{ 0x1e, 0x0000ffff, 0, 0 },
	{ 0x1e, 0xffff0000, 16, 0 },
	{ 0x1f, 0x0000ffff, 0, 0 },
	{ 0x1f, 0xffff0000, 16, 0 },
	{ 0x20, 0x0000ffff, 0, 0 },
	{ 0x6d, 0x0000ffff, 0, 0xb4 },
	{ 0xffffffff }
};

static struct reg cac_weights_oland_xt[] = {
	{ 0x0, 0x0000ffff, 0, 0x43 },
	{ 0x0, 0xffff0000, 16, 0x29 },
	{ 0x1, 0x0000ffff, 0, 0xaf },
	{ 0x1, 0xffff0000, 16, 0x2a },
	{ 0x2, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0x0000ffff, 0, 0xa0 },
	{ 0x3, 0xffff0000, 16, 0x29 },
	{ 0x4, 0x0000ffff, 0, 0xa0 },
	{ 0x4, 0xffff0000, 16, 0x59 },
	{ 0x5, 0x0000ffff, 0, 0x1a5 },
	{ 0x5, 0xffff0000, 16, 0x1d6 },
	{ 0x6, 0x0000ffff, 0, 0x2a3 },
	{ 0x6, 0xffff0000, 16, 0x8fd },
	{ 0x18f, 0x0000ffff, 0, 0x76 },
	{ 0x7, 0x0000ffff, 0, 0x8a },
	{ 0x7, 0xffff0000, 16, 0xa3 },
	{ 0x8, 0x0000ffff, 0, 0x71 },
	{ 0x8, 0xffff0000, 16, 0x36 },
	{ 0x9, 0x0000ffff, 0, 0xa6 },
	{ 0xa, 0x0000ffff, 0, 0x81 },
	{ 0xb, 0x0000ffff, 0, 0x3d2 },
	{ 0xb, 0xffff0000, 16, 0x27c },
	{ 0xc, 0x0000ffff, 0, 0xa96 },
	{ 0xd, 0x0000ffff, 0, 0x5 },
	{ 0xd, 0xffff0000, 16, 0x5 },
	{ 0xe, 0x0000ffff, 0, 0xb },
	{ 0xf, 0x0000ffff, 0, 0x3 },
	{ 0xf, 0xffff0000, 16, 0x2 },
	{ 0x10, 0x0000ffff, 0, 0x1 },
	{ 0x10, 0xffff0000, 16, 0x4 },
	{ 0x11, 0x0000ffff, 0, 0x15 },
	{ 0x11, 0xffff0000, 16, 0x7 },
	{ 0x12, 0x0000ffff, 0, 0x36 },
	{ 0x13, 0x0000ffff, 0, 0x10 },
	{ 0x13, 0xffff0000, 16, 0x10 },
	{ 0x14, 0x0000ffff, 0, 0x120 },
	{ 0x15, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0xffff0000, 16, 0x6 },
	{ 0x4e, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0x0000ffff, 0, 0x32 },
	{ 0x16, 0xffff0000, 16, 0x7e },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0x280 },
	{ 0x1a, 0xffff0000, 16, 0x7 },
	{ 0x1b, 0x0000ffff, 0, 0x0 },
	{ 0x1b, 0xffff0000, 16, 0x0 },
	{ 0x1c, 0x0000ffff, 0, 0x3c },
	{ 0x1c, 0xffff0000, 16, 0x203 },
	{ 0x1d, 0x0000ffff, 0, 0x0 },
	{ 0x1d, 0xffff0000, 16, 0x0 },
	{ 0x1e, 0x0000ffff, 0, 0 },
	{ 0x1e, 0xffff0000, 16, 0 },
	{ 0x1f, 0x0000ffff, 0, 0 },
	{ 0x1f, 0xffff0000, 16, 0 },
	{ 0x20, 0x0000ffff, 0, 0 },
	{ 0x6d, 0x0000ffff, 0, 0xb4 },
	{ 0xffffffff }
};

static struct reg cac_weights_oland[] = {
	{ 0x0, 0x0000ffff, 0, 0x82 },
	{ 0x0, 0xffff0000, 16, 0x4f },
	{ 0x1, 0x0000ffff, 0, 0x153 },
	{ 0x1, 0xffff0000, 16, 0x52 },
	{ 0x2, 0x0000ffff, 0, 0x0 },
	{ 0x3, 0x0000ffff, 0, 0x135 },
	{ 0x3, 0xffff0000, 16, 0x4f },
	{ 0x4, 0x0000ffff, 0, 0x135 },
	{ 0x4, 0xffff0000, 16, 0xac },
	{ 0x5, 0x0000ffff, 0, 0x118 },
	{ 0x5, 0xffff0000, 16, 0xbe },
	{ 0x6, 0x0000ffff, 0, 0x110 },
	{ 0x6, 0xffff0000, 16, 0x4cd },
	{ 0x18f, 0x0000ffff, 0, 0x30 },
	{ 0x7, 0x0000ffff, 0, 0x37 },
	{ 0x7, 0xffff0000, 16, 0x27 },
	{ 0x8, 0x0000ffff, 0, 0xc3 },
	{ 0x8, 0xffff0000, 16, 0x35 },
	{ 0x9, 0x0000ffff, 0, 0x28 },
	{ 0xa, 0x0000ffff, 0, 0x26c },
	{ 0xb, 0x0000ffff, 0, 0x3b2 },
	{ 0xb, 0xffff0000, 16, 0x99d },
	{ 0xc, 0x0000ffff, 0, 0xa3f },
	{ 0xd, 0x0000ffff, 0, 0xa },
	{ 0xd, 0xffff0000, 16, 0xa },
	{ 0xe, 0x0000ffff, 0, 0x5 },
	{ 0xf, 0x0000ffff, 0, 0x3 },
	{ 0xf, 0xffff0000, 16, 0x0 },
	{ 0x10, 0x0000ffff, 0, 0x1 },
	{ 0x10, 0xffff0000, 16, 0x1 },
	{ 0x11, 0x0000ffff, 0, 0x5 },
	{ 0x11, 0xffff0000, 16, 0x15 },
	{ 0x12, 0x0000ffff, 0, 0x34 },
	{ 0x13, 0x0000ffff, 0, 0x4 },
	{ 0x13, 0xffff0000, 16, 0x4 },
	{ 0x14, 0x0000ffff, 0, 0x3ba },
	{ 0x15, 0x0000ffff, 0, 0x0 },
	{ 0x15, 0xffff0000, 16, 0x6 },
	{ 0x4e, 0x0000ffff, 0, 0x0 },
	{ 0x16, 0x0000ffff, 0, 0x30 },
	{ 0x16, 0xffff0000, 16, 0x7a },
	{ 0x17, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0x0000ffff, 0, 0x0 },
	{ 0x18, 0xffff0000, 16, 0x0 },
	{ 0x19, 0x0000ffff, 0, 0x0 },
	{ 0x19, 0xffff0000, 16, 0x0 },
	{ 0x1a, 0x0000ffff, 0, 0 },
	{ 0x1a, 0xffff0000, 16, 0 },
	{ 0x1b, 0x0000ffff, 0, 0 },
	{ 0x1b, 0xffff0000, 16, 0 },
	{ 0x1c, 0x0000ffff, 0, 0 },
	{ 0x1c, 0xffff0000, 16, 0 },
	{ 0x1d, 0x0000ffff, 0, 0 },
	{ 0x1d, 0xffff0000, 16, 0 },
	{ 0x1e, 0x0000ffff, 0, 0 },
	{ 0x1e, 0xffff0000, 16, 0 },
	{ 0x1f, 0x0000ffff, 0, 0 },
	{ 0x1f, 0xffff0000, 16, 0 },
	{ 0x20, 0x0000ffff, 0, 0 },
	{ 0x6d, 0x0000ffff, 0, 0x100 },
	{ 0xffffffff }
};

static struct reg *lcac_get(struct pci_dev *dev)
{
	struct dev_drv_data *dd;
	dd = pci_get_drvdata(dev);

	switch (dd->family) {
	case TAHITI:
		return &lcac_tahiti[0];
	case PITCAIRN:
		return &lcac_pitcairn[0];
	case VERDE:
		return &lcac_cape_verde[0];
	case OLAND:
		switch (dev->device) {
		case 0x6601:
		case 0x6621:
		case 0x6603:
		case 0x6600:
		case 0x6606:
		case 0x6620:
		case 0x6611:
		case 0x6610:
			return &lcac_mars_pro[0];
		default:
			return &lcac_oland[0];
		};
	}
	unreachable();
}

static struct reg *cac_weights_get(struct pci_dev *dev)
{
	struct dev_drv_data *dd;
	dd = pci_get_drvdata(dev);

	switch (dd->family) {
	case TAHITI:
		return &cac_weights_tahiti[0];
	case PITCAIRN:
		return &cac_weights_pitcairn[0];
	case VERDE:
		switch (dev->device) {
		case 0x683b:
		case 0x683f:
		case 0x6829:
		case 0x6835:
			return &cac_weights_cape_verde_pro[0];
		case 0x6825:
		case 0x6827:
		case 0x6820:
		case 0x6821:
			return &cac_weights_heathrow[0];
		case 0x6824:
		case 0x682d:
			return &cac_weights_chelsea_xt[0];	
		case 0x682f:
		case 0x6823:
		case 0x682b:
			return &cac_weights_chelsea_pro[0];
		default:
			return &cac_weights_cape_verde[0];
		};
	case OLAND:
		switch (dev->device) {
		case 0x6601:
		case 0x6621:
		case 0x6603:
			return &cac_weights_mars_pro[0];
		case 0x6600:
		case 0x6606:
		case 0x6620:
			return &cac_weights_mars_xt[0];
		case 0x6611:
			return &cac_weights_oland_pro[0];
		case 0x6610:
			return &cac_weights_oland_xt[0];
		default:
			return &cac_weights_oland[0];
		};
	}
	unreachable();
}

void regs_wr(struct pci_dev *dev, struct reg *r)
{
	while (r->of != 0xffffffff) {
		u32 r_of;
		u32 val;

		r_of = SMC_CG_IND_START + r->of;
		val = smc_r32(dev, r_of);
		LOG("rd:of=0x%08x val=0x%08x",r_of,val);

		val &= ~r->mask;
		val |= ((r->val << r->shift) & r->mask);

		LOG("wr:of=0x%08x val=0x%08x",r_of,val);
		smc_w32(dev, val, r_of);
		++r;
	}
}

void smc_cac_cfg_regs_init(struct pci_dev *dev)
{
	struct reg *lcac;
	struct reg *cac_weights;

	LOG("setting calculation accumulator configuration registers");

	lcac = lcac_get(dev);
	cac_weights = cac_weights_get(dev);

	LOG("LCAC REGS START");
	regs_wr(dev, lcac);
	LOG("LCAC REGS END");

	LOG("CAC_WEIGHTS REGS START");
	regs_wr(dev, cac_weights);
	LOG("CAC_WEIGHTS REGS END");
}
